package cn.tedu.charging.order.websocket;

/**
 * 对标 controller
 */

import cn.tedu.charging.common.protocol.WebSocketMessage;
import com.alibaba.fastjson2.JSON;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;

@Component
@ServerEndpoint("/ws/server/{userId}")//requestMapping类似功能 提供一个长连接发起请求的连接路径
public class WebSocketServer {
    Logger logger = Logger.getLogger(WebSocketServer.class.getName());
    /**
     * webSocket终端server 要定义链接过程中所有的方法
     * 包括 开始创建连接
     * 包括 连接断开
     * 包括 消息发送等
     * 包括 连接过程出现异常问题
     */
    /**
     * 扩展一个服务端推送消息给用户的方法 pushMessage
     */
    public void pushMessage(Integer userId,String message){
        //1.userId可以获取session 只要这个用户连接没有断开
        Session session = USERS.get(userId);//没连接 或者连接断开 TODO 连接断开的时候 清除该用户session
        //2.message利用session 发送出去
        if (session!=null){
            try {
                session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                logger.info("消息发送失败,原因:"+e.getMessage());
            }
        }else{
            //发送到消息队列
            logger.info("拿不到该用户连接");
        }
    }
    /**
     * 开启连接,每次客户端建立长连接 都会调用onOpen同时创建一个内存的session对象
     * 可以在onOpen接收这个对象进行session管理
     */
    private static Map<Integer,Session> USERS=new ConcurrentHashMap<>();
    @OnOpen
    public void onOpen(Session session,@PathParam("userId") Integer userId){
        logger.info("客户端创建连接");
        logger.info("sessionId:"+session.getId());
        logger.info("建立连接的用户:"+userId);
        //应该在这个创建发起连接的过程干什么 将前端传递的用户userId 与连接会话 建立映射
        USERS.put(userId,session);
    }
    /**
     * 客户端断开连接
     * 断开连接的时候,框架也会调用onClose 接受哪个session断开了
     */
    @OnClose
    public void onClose(Session session,@PathParam("userId") Integer userId){
        logger.info("客户端断开连接");
        logger.info("sessionId:"+session.getId());
        //清空session映射
        USERS.remove(userId);
    }
    /**
     * 连接过程出现异常问题
     * 出现异常问题的时候 也需要明确是哪个session的问题
     */
    @OnError
    public void onError(Session session,Throwable e){
        logger.info("客户端连接出现异常:"+e.getMessage());
        logger.info("sessionId:"+session.getId());
    }
    /**
     * 双方有消息通信的过程
     * 客户端向服务端发送信息
     * 接到客户端的消息,也可以知道消息来自于哪个会话session
     */
    @OnMessage
    public void onMessage(Session session,String message) throws IOException {
        logger.info("客户端发送信息:"+message);
        logger.info("消息来自于session:"+session.getId());
        //谁给我发消息,我就给谁回消息,使用session的api发送消息
        WebSocketMessage webSocketMessage = new WebSocketMessage<>();
        webSocketMessage.setState(4);
        webSocketMessage.setMessage("你好我是服务端");
        webSocketMessage.setData(null);
        session.getBasicRemote().sendText(JSON.toJSONString(webSocketMessage));
    }
}
